home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-31 | 76.0 KB | 1,867 lines | [TEXT/R*ch] |
- C.S.M.P. Digest Thu, 24 Aug 95 Volume 3 : Issue 108
-
- Today's Topics:
-
- Asynchronous File I-O
- Saving and restoring current drawing port - necessary?
- Where are my command line arguments?
-
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
- (pottier@clipper.ens.fr).
-
- The digest is a collection of article threads from the internet newsgroups
- comp.sys.mac.programmer.help, csmp.tools and csmp.misc. It is designed for
- people who read news semi-regularly and want an archive of the discussions.
- If you don't know what a newsgroup is, you probably don't have access to
- it. Ask your systems administrator(s) for details. If you don't have access
- to news, you may still be able to post messages to the group by using a
- mail server like anon.penet.fi (mail help@anon.penet.fi for more
- information).
-
- Each issue of the digest contains one or more sets of articles (called
- threads), with each set corresponding to a 'discussion' of a particular
- subject. The articles are not edited; all articles included in this digest
- are in their original posted form (as received by our news server at
- nef.ens.fr). Article threads are not added to the digest until the last
- article added to the thread is at least two weeks old (this is to ensure that
- the thread is dead before adding it to the digest). Article threads that
- consist of only one message are generally not included in the digest.
-
- The digest is officially distributed by two means, by email and ftp.
-
- If you want to receive the digest by mail, send email to listserv@ens.fr
- with no subject and one of the following commands as body:
- help Sends you a summary of commands
- subscribe csmp-digest Your Name Adds you to the mailing list
- signoff csmp-digest Removes you from the list
- Once you have subscribed, you will automatically receive each new
- issue as it is created.
-
- The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
- Questions related to the ftp site should be directed to
- scott.silver@dartmouth.edu.
-
- -------------------------------------------------------
-
- >From domarkmk@aol.com (Domark MK)
- Subject: Asynchronous File I-O
- Date: 27 Jul 1995 23:54:02 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- After many hours of wasted time today, I've learned that asynchronous file
- I/O isn't possible on the Mac, at least until Apple rewrites the SCSI
- Manager. I've heard that SCSI Manager 4.3 fixes that "for some machines",
- but I have it installed and it's not having any effect, and I need it to
- work for all machines (well, all PowerPC machines, including the upgrade
- cards). I came across some code that makes async file calls from Time
- Manager completion routines, and tried that, but of course everything
- still stops as soon as the read is initiated and doesn't continue until
- it's finished. I also found the async I/O Thread Manager code, but I
- haven't tried it because I believe it will behave the same as the Time
- Manager 'asynchronous' I/O.
-
- All I want is to be able to read from a CD, while continuously drawing
- stuff on the screen. (I'm playing an animation from the disk, using a
- double-buffering technique that relies on asynchronous reads.) Is it
- possible? Can it be done? Does anyone have a sledgehammer I can borrow?
-
- Thanks,
-
- Mike.
-
- ________________________________________________________________________
- Michael A. Kelly Senior Software Engineer
- mkelly@domark.com Domark Software, Inc.
- ________________________________________________________________________
-
- +++++++++++++++++++++++++++
-
- >From jumplong@aol.com (Jump Long)
- Date: 29 Jul 1995 02:25:59 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- In article <3v9n0q$gfr@newsbf02.news.aol.com> Domark MK, domarkmk@aol.com
- writes:
-
- >After many hours of wasted time today, I've learned that
- >asynchronous file I/O isn't possible on the Mac, at least until
- >Apple rewrites the SCSI Manager. I've heard that SCSI Manager
- >4.3 fixes that "for some machines", but I have it installed and
- >it's not having any effect, and I need it to work for all
- >machines (well, all PowerPC machines, including the upgrade
- >cards).
-
- The File Manager handles asynchronous requests now (and always has).
- However, there are certain limitations that make asynchronous File Manager
- requests only semi-useful.
-
- The first limitation is the Macintosh file system (and much of the rest of
- the operating system) is currently single-threaded. That means that you
- can have a dozen asynchronous requests outstanding but they execute one at
- a time. The asynchronous requests that are waiting are kept in an OS
- queue and are handled (except in the special cases of retries and to
- remote AppleShare volumes) first in / first out.
-
- The next limitation is that many device drivers and the SCSI Manager
- before SCSI Manager 4.3 handle all requests synchronously. So, even
- though the File Manager calls the device driver asynchronously (because
- the File Manager request was made asynchronously), the device driver or
- SCSI Manager doesn't return control to the file system until the call is
- complete.
-
- I guess a short overview of how the file system works might help here.
- I'll use a Read as an example of what happens. I'm going to leave out
- lots of the minor details, but you should get the general idea...
-
- When you make a Read request to the File Manager, it looks at the trap
- word and sets a flag for itself if the async bit is set. Then it continues
- the handling of the Read; it makes sure the file is open with read access,
- calculates the offset where the Read should begin, and calls the routine
- that figures out where the file blocks to be read are on the disk.
-
- Now, the File Manager is ready to read the data from the disk, so it needs
- to call the disk driver that owns the volume to read 1 or more blocks.
- The File Manager checks the "async" flag and if the File Manager request
- was asynchronous, then it calls the disk driver asynchronously (with a
- completion routine) to read the blocks; if the request was synchronous,
- then it calls the disk driver synchronously.
-
- If the call was made asynchronously, then when the File Manager gets
- control back, it returns control to the code that made the original File
- Manager request. Meanwhile, the disk driver reads the disk. When the disk
- driver finishes and calls the completion routine, the File Manager has
- control again and continues handling the Read request. (If more disk I/O
- is needed, it is made asynchronously again.) When the File Manager has
- fulfilled the Read request, it sets the result code in the parameter
- block, it calls the completion routine for the asynchronous File Manager
- request (if there was one), and then checks to see if it needs to start
- handling another queued request. If not, control is returned to whatever
- was interrupted.
-
- As you can see, if the disk driver handles asynchronous requests to it
- synchronously, then the program that called the File Manager
- asynchronously never gets any time back before the call is complete.
- Also, since the File Manager is single-threaded, a synchronous driver
- blocks all queued calls behind it.
-
- So, what works now? The AppleShare foreign file system has always handled
- almost all calls asynchronously so your program can get control back while
- your request is handled by an AppleShare file server. With SCSI Manager
- 4.3 and the proper asynchronous SCSI disk drivers on on all 040 and
- PowerPC based systems.
-
- So, why are asynchronous calls still useful, even when the disk driver is
- synchronous? Because you can make asynchronous requests at interrupt time
- without causing the file system to deadlock (if the file system is
- handling a call and you interrupt it and make a synchronous file system
- call, the file system can't finish what it's doing and can't give you
- control back... that's deadlock).
-
- I hope that kind of clears things up for you. When we get a multi-threaded
- operating system on the Macintosh, things will be even better. You might
- want to read the "develop" magazine article I wrote for issue #13 if you
- can find it. It covers asynchronous programming techniques in detail.
-
- - Jim Luther
-
- +++++++++++++++++++++++++++
-
- >From domarkmk@aol.com (Domark MK)
- Date: 29 Jul 1995 17:13:05 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- >>
- SCSI Manager 4.3
- provides asynchronous disk i/o, ASSUMING your driver supports asynchronous
- disk i/o.
- <<
-
- OK, so when will I be able to assume that most everyone with a PowerMac
- has drivers for their cd-roms that support asynchronous i/o? Is the
- driver in the hardware or is it in the Apple CD-ROM extensions (or their
- third-party substitutes)? Is there a new version of the Apple CD-ROM
- extensions that support async i/o? If so, could I include it with my
- software so that I could then assume they have a driver that supports
- async i/o?
-
- Or do I just have to reduce the quality of my animation because of the
- limitations of prior versions of the system software? (As I see it, async
- support would be standard in current drivers if the Mac OS had supported
- it sooner.)
-
- Mike.
-
- ________________________________________________________________________
- Michael A. Kelly Senior Software Engineer
- mkelly@domark.com Domark Software, Inc.
- ________________________________________________________________________
-
- +++++++++++++++++++++++++++
-
- >From blob@apple.com (Brian Bechtel)
- Date: Sat, 29 Jul 1995 21:55:36 -0700
- Organization: Apple Computer, Inc.
-
- In article <3ve891$mjh@newsbf02.news.aol.com>, domarkmk@aol.com (Domark
- MK) wrote:
- > OK, so when will I be able to assume that most everyone with a PowerMac
- > has drivers for their cd-roms that support asynchronous i/o?
-
- I'm not sure anyone can answer this question...
-
- >Is the driver in the hardware
-
- No. The driver is the software which understands how to talk to the hardware.
-
- >or is it in the Apple CD-ROM extensions (or their third-party substitutes)?
-
- For the Apple CD-ROM software, the driver is called "Apple CD-ROM".
- Apple's driver only supports Apple CD-ROM drives; you have to use third
- party drivers for third party drives. Look at
- http://www.info.apple.com/dev/devinfo/maccdromfaq.html#thirdparty
- for some third party drivers.
-
- >Is there a new version of the Apple CD-ROM extensions that support
- >async i/o?
-
- I'm not sure what versions didn't support asynchronous i/o, if any.
-
- >If so, could I include it with my software so that I could then
- > assume they have a driver that supports async i/o?
-
- If you want to redistribute Apple software, you have to contact Apple's
- software licensing department at sw.license@applelink.apple.com. You'll
- have to contact the authors of third party software to find their
- redistribution requirements.
-
- --
- --Brian Bechtel blob@apple.com Village Idiot, DTS
-
- +++++++++++++++++++++++++++
-
- >From domarkmk@aol.com (Domark MK)
- Date: 1 Aug 1995 12:35:43 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- >>Is there a new version of the Apple CD-ROM extensions that support
- >>async i/o?
- >
- >I'm not sure what versions didn't support asynchronous i/o, if any.
-
- Hmmm, so if I have SCSI Manager 4.3.1, and Apple CD-ROM 5.0.1, and an
- Apple CD300, PBReadAsync should work asynchronously? It doesn't....
- Could it be that the hardware doesn't support async i/o?
-
- Mike.
- ________________________________________________________________________
- Michael A. Kelly Senior Software Engineer
- mkelly@domark.com Domark Software, Inc.
- ________________________________________________________________________
-
- +++++++++++++++++++++++++++
-
- >From domarkmk@aol.com (Domark MK)
- Date: 1 Aug 1995 12:35:43 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- >>Is there a new version of the Apple CD-ROM extensions that support
- >>async i/o?
- >
- >I'm not sure what versions didn't support asynchronous i/o, if any.
-
- Hmmm, so if I have SCSI Manager 4.3.1, and Apple CD-ROM 5.0.1, and an
- Apple CD300, PBReadAsync should work asynchronously? It doesn't....
- Could it be that the hardware doesn't support async i/o?
-
- Mike.
- ________________________________________________________________________
- Michael A. Kelly Senior Software Engineer
- mkelly@domark.com Domark Software, Inc.
- ________________________________________________________________________
-
- ---------------------------
-
- >From duncant@sushi.mitre.or.jp (Duncan Thomson)
- Subject: Saving and restoring current drawing port - necessary?
- Date: Thu, 20 Jul 1995 09:31:12 +0530
- Organization: Nothing to do with my organization
-
- Hi, Mac programming novice here with a question...
-
- The "Inside Mac" books say that, before setting the current port (when you
- want to draw in it), you should save the previous port, then, after you
- are done drawing, set it back to what it was. (Written in a confusing
- manner, I admit, but I think you know what I'm talking about.)
-
- My question: Is this really necessary? If all code sets the port as
- necessary before drawing in it, why bother to restore it? Is there some
- problem with asynchronous processing going on here?
-
- Thanks
- Duncan
-
- p.s. Please e-mail me your response, as well as posting (if you think it's
- worth posting at all) as my news server is unreliable, and I may miss your
- answer if you just post.
-
- +++++++++++++++++++++++++++
-
- >From peter@adi.co.nz (Peter Bromley)
- Date: Fri, 21 Jul 1995 17:41:26 +1200
- Organization: ADInstruments
-
- In article <3umsqt$ocg@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
- (Sean Crist) wrote:
-
- > In article <duncant-2007950931120001@a09.dial.twics.com>,
- > Duncan Thomson <duncant@sushi.mitre.or.jp> wrote:
- > >Hi, Mac programming novice here with a question...
- > >
- > >The "Inside Mac" books say that, before setting the current port (when you
- > >want to draw in it), you should save the previous port, then, after you
- > >are done drawing, set it back to what it was. (Written in a confusing
- > >manner, I admit, but I think you know what I'm talking about.)
- > >
- > >My question: Is this really necessary? If all code sets the port as
- > >necessary before drawing in it, why bother to restore it? Is there some
- > >problem with asynchronous processing going on here?
- >
- > Well, I almost never do this, myself, and I've never had any problems. My
- > personal programming policy is that it's every routine for itself as far as
- > the port is concerned; if a routine is expecting the port to be
- > such-and-such, it's that routine's responsibility to set it itself. This
- > saves me from having to trace back through a dozen routines to see who
- > changed the port.
- >
-
- As if its all that difficult to do the right thing. All you need to do is
- use the GetPort, SetPort, code, SetPort combination as a response to the
- following things
-
- Events
- (update, activate, mousedown, keydown, appleevent),
- Internal program "events"
- (idle, checkmouseshape, checknextWNEsleep, somedatachanged, dosomething)
-
- If you do this right you need never set the port elsewhere (except to work
- with offscreen bitmaps / printing / ... well, maybe some other times) :-)
-
- > I _might_ make an exception (i.e. and save and restore the port) if I had
- > some routine which did drawing in a certain port and was frequently called
- > from within other routines which needed the port to be something in
- > particular, so that calling this drawing routine would be transparent. But
- > in practice I find that I never need to do this.
- >
-
- See, if you did it _right_, you wouldnt ever need to protect individual
- routines ever.
-
-
- BTW: If IM says do something, you'ld have to be a fool or an expert to do
- otherwise (IMO of course).
-
- --
- Peter Bromley (peter@adi.co.nz)
- ADInstruments, Dunedin, New Zealand
-
- +++++++++++++++++++++++++++
-
- >From pandhphot@aol.com (PandH Phot)
- Date: 20 Jul 1995 20:16:40 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- You'll find that often the current port is the monitor's "world". If you
- don't restore it and somebody tries to write to the monitor, bad things
- might happen. If you're always using modal dialogs you might get away with
- it, since they rule the world while they live and die oblivious to their
- neighbors, but I'm not even sure I'd count on that in the brave new
- permanent-Multifinder society we live in.
-
- Besides, it's so easy, why fight it?
-
- Paul
-
- +++++++++++++++++++++++++++
-
- >From kurisuto@babel.ling.upenn.edu (Sean Crist)
- Date: 21 Jul 1995 12:10:43 GMT
- Organization: University of Pennsylvania, Linguistics Department
-
- In article <peter-2107951741260001@adi008.adi.co.nz>,
- Peter Bromley <peter@adi.co.nz> wrote:
- >In article <3umsqt$ocg@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
- >(Sean Crist) wrote:
-
- >> Well, I almost never do this, myself, and I've never had any problems. My
- >> personal programming policy is that it's every routine for itself as far as
- >> the port is concerned; if a routine is expecting the port to be
- >> such-and-such, it's that routine's responsibility to set it itself. This
- >> saves me from having to trace back through a dozen routines to see who
- >> changed the port.
- >
- >As if its all that difficult to do the right thing. All you need to do is
- >use the GetPort, SetPort, code, SetPort combination as a response to the
- >following things
-
- *shrug* I wasn't aware that this was an issue on which there is a "right"
- way to do things. Your way works, but I don't see what's wrong with my
- way, as it works too, and doesn't violate any of Apple's rules (I think
- they included GetPort so that you _can_ preserve the port, not because you
- _have_ to).
-
- Really, I think it's personal preference, and the important thing is that
- you pick a scheme and then _be consistant_ with it. Since none of my
- routines make assumptions about what the port should be (with a very few
- exceptions which I always document clearly in my comments), none of them
- need to preserve it either, and I never run into trouble.
-
- >> I _might_ make an exception (i.e. and save and restore the port) if I had
- >> some routine which did drawing in a certain port and was frequently called
- >> from within other routines which needed the port to be something in
- >> particular, so that calling this drawing routine would be transparent. But
- >> in practice I find that I never need to do this.
- >
- >See, if you did it _right_, you wouldnt ever need to protect individual
- >routines ever.
- >
- >BTW: If IM says do something, you'ld have to be a fool or an expert to do
- >otherwise (IMO of course).
-
- I agree that IM should be rigorously followed. But I don't agree that I'm
- outside IM's rules here. I'd be quite shocked to learn that IM somewhere
- says "If your routines change the port internally, they must always
- remember and restore the current port, and if you don't do this, your
- application is likely to break under future system releases." The
- important point is that the port be correctly set at times when it matters,
- and there's more than one overall scheme for ensuring that this is so.
-
-
- \/ __ __ _\_ --Sean Crist (kurisuto@unagi.cis.upenn.edu)
- --- | | \ /
- _| ,| ,| ----- For a free copy of the Bill of Rights, finger
- _| ,| ,| [_] this account.
- | | | [_]
-
-
-
- +++++++++++++++++++++++++++
-
- >From kurisuto@babel.ling.upenn.edu (Sean Crist)
- Date: 21 Jul 1995 00:36:45 GMT
- Organization: University of Pennsylvania, Linguistics Department
-
- In article <duncant-2007950931120001@a09.dial.twics.com>,
- Duncan Thomson <duncant@sushi.mitre.or.jp> wrote:
- >Hi, Mac programming novice here with a question...
- >
- >The "Inside Mac" books say that, before setting the current port (when you
- >want to draw in it), you should save the previous port, then, after you
- >are done drawing, set it back to what it was. (Written in a confusing
- >manner, I admit, but I think you know what I'm talking about.)
- >
- >My question: Is this really necessary? If all code sets the port as
- >necessary before drawing in it, why bother to restore it? Is there some
- >problem with asynchronous processing going on here?
-
- Well, I almost never do this, myself, and I've never had any problems. My
- personal programming policy is that it's every routine for itself as far as
- the port is concerned; if a routine is expecting the port to be
- such-and-such, it's that routine's responsibility to set it itself. This
- saves me from having to trace back through a dozen routines to see who
- changed the port.
-
- I _might_ make an exception (i.e. and save and restore the port) if I had
- some routine which did drawing in a certain port and was frequently called
- from within other routines which needed the port to be something in
- particular, so that calling this drawing routine would be transparent. But
- in practice I find that I never need to do this.
-
- \/ __ __ _\_ --Sean Crist (kurisuto@unagi.cis.upenn.edu)
- --- | | \ /
- _| ,| ,| ----- For a free copy of the Bill of Rights, finger
- _| ,| ,| [_] this account.
- | | | [_]
-
-
-
- +++++++++++++++++++++++++++
-
- >From Charles B. Cranston <zben@ni.umd.edu>
- Date: 21 Jul 1995 18:22:23 GMT
- Organization: Network Infrastructures UMD CSC
-
- > Is it really necessary to save and restore the current port
- > and set the desired port before and after any drawing?
-
- I've used both philosophies:
-
- 1. "Every routine for himself" - religiously set the port before any
- drawing, the current port is irrelevant at any other time.
-
- 2. "Keep the port set to the frontmost window" - religiosly set the
- current port every activate, deactivate etc.
-
- I remember back in the pre-Multifinder days (System 6) there was a
- Mac Tech Note describing a gotcha situation between applications and
- desk accessories (which USED to run in application space but were
- moved to Finder's space in Multifinder and System 7).
-
- In the worst case, two badly coded DAs could crash each other without
- the application being able to do anything about it! But there were
- other cases of DA vs application crashes that could be avoided if you
- made sure there was a valid current port befor giving the DA time.
-
- I don't think this can happen anymore. Anybody know?
-
- +-+-+
- Charles B. (Ben) Cranston <zben@ni.umd.edu>
- http://www.wam.umd.edu/~zben
-
- +++++++++++++++++++++++++++
-
- >From mouser@zercom.net (Martin-Gilles Lavoie)
- Date: 24 Jul 1995 16:23:32 GMT
- Organization: zercom technologies inc.
-
- In article <3uor8v$3b6@mimsy.cs.umd.edu>, Charles B. Cranston
- <zben@ni.umd.edu> wrote:
-
- > > Is it really necessary to save and restore the current port
- > > and set the desired port before and after any drawing?
- >
- > I've used both philosophies:
- >
- > 1. "Every routine for himself" - religiously set the port before any
- > drawing, the current port is irrelevant at any other time.
- >
- > 2. "Keep the port set to the frontmost window" - religiosly set the
- > current port every activate, deactivate etc.
- >
- > I remember back in the pre-Multifinder days (System 6) there was a
- > Mac Tech Note describing a gotcha situation between applications and
- > desk accessories (which USED to run in application space but were
- > moved to Finder's space in Multifinder and System 7).
- >
- > In the worst case, two badly coded DAs could crash each other without
- > the application being able to do anything about it! But there were
- > other cases of DA vs application crashes that could be avoided if you
- > made sure there was a valid current port befor giving the DA time.
- >
- > I don't think this can happen anymore. Anybody know?
- >
-
- I've had extensions crewing up my view ports now and then. Some still
- do. I dont take a chance. As to setting the port to every
- activate/deactivate events. this may be overkill (although, it doesn't
- take much CPU time..). To be safe, I always set my port before drawing.
- On activate, it'd be only usefull if I wanted to track the cursor position
- relative to the window position.
-
- --
- Martin-Gilles Lavoie
-
- MPW: Because life is too complicated for CodeWarrior.
- --MGL
-
- +++++++++++++++++++++++++++
-
- >From peter@adi.co.nz (Peter Bromley)
- Date: Sun, 23 Jul 1995 15:40:53 +1200
- Organization: ADInstruments
-
- In article <3uo5g3$kbm@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
- (Sean Crist) wrote:
-
- > In article <peter-2107951741260001@adi008.adi.co.nz>,
- > Peter Bromley <peter@adi.co.nz> wrote:
- > >In article <3umsqt$ocg@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
- > >(Sean Crist) wrote:
- >
- > >> Well, I almost never do this, myself, and I've never had any problems. My
- > >> personal programming policy is that it's every routine for itself as far as
- > >> the port is concerned; if a routine is expecting the port to be
- > >> such-and-such, it's that routine's responsibility to set it itself. This
- > >> saves me from having to trace back through a dozen routines to see who
- > >> changed the port.
- > >
- > >As if its all that difficult to do the right thing. All you need to do is
- > >use the GetPort, SetPort, code, SetPort combination as a response to the
- > >following things
- >
- > *shrug* I wasn't aware that this was an issue on which there is a "right"
- > way to do things. Your way works, but I don't see what's wrong with my
- > way, as it works too, and doesn't violate any of Apple's rules (I think
- > they included GetPort so that you _can_ preserve the port, not because you
- > _have_ to).
- >
-
- Hmmmm, I guess I didnt express myself very clearly. And perhaps you are
- right - the NIM snippets dont seem to advocate protecting the current port
- at all. I guess my approach has arisin from discovering that whenever I
- found a current port related bug (like system font getting trashed, or
- LocalToGlobal doing weird things) I found that the port was not what I
- expected. My code policy evolved out from that to the (I guess) paranoid,
- but safe approach of making sure the port is what I want it to be but -
- just in case - always restoring the current port as well. I found it was
- easier to do this as close to my main event loop as possible and got the
- added bonus that lower level routines could assume the port was always
- correct.
-
- BTW: these problems dont just come up with regard to the current port. I
- still find it difficult to setle on _one_ scheme for lots of other things,
- like pen and text settings within a port, foreground colour, and so on.
- The situation gets trickier, too, when you're not the only one working on
- a program. Differing approaches can cause lots of obscure bugs in a
- multi-person project ;-)
-
- --
- Peter Bromley (peter@adi.co.nz)
- ADInstruments, Dunedin, New Zealand
-
- +++++++++++++++++++++++++++
-
- >From Richard Wesley <hawkfish@punchdeck.com>
- Date: 23 Jul 1995 23:28:17 GMT
- Organization: Punch Deck Consulting
-
- peter@adi.co.nz (Peter Bromley) wrote:
- >In article <3umsqt$ocg@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
- >(Sean Crist) wrote:
- >
- >> In article <duncant-2007950931120001@a09.dial.twics.com>,
- >> Duncan Thomson <duncant@sushi.mitre.or.jp> wrote:
- >> >Hi, Mac programming novice here with a question...
- >> >
- >> >The "Inside Mac" books say that, before setting the current port (when you
- >> >want to draw in it), you should save the previous port, then, after you
- >> >are done drawing, set it back to what it was. (Written in a confusing
- >> >manner, I admit, but I think you know what I'm talking about.)
- >> >
- >> >My question: Is this really necessary? If all code sets the port as
- >> >necessary before drawing in it, why bother to restore it? Is there some
- >> >problem with asynchronous processing going on here?
- >>
- >> Well, I almost never do this, myself, and I've never had any problems. My
- >> personal programming policy is that it's every routine for itself as far as
- >> the port is concerned; if a routine is expecting the port to be
- >> such-and-such, it's that routine's responsibility to set it itself. This
- >> saves me from having to trace back through a dozen routines to see who
- >> changed the port.
- >>
- >
- >As if its all that difficult to do the right thing. All you need to do is
- >use the GetPort, SetPort, code, SetPort combination as a response to the
- >following things
- >
- >Events
- > (update, activate, mousedown, keydown, appleevent),
- >Internal program "events"
- > (idle, checkmouseshape, checknextWNEsleep, somedatachanged, dosomething)
- >
-
- If you're using CW PowerPlant, you can even use the utility class StPortOriginState to save the state, then all you have to do is is=
- sue a declaration and C++ will clean it all up for you (even if an exception is thrown.)
-
- If you're not using PP, just do something like
-
- class StPortState {
- GrafPtr mSave;
- public:
- StPortState (GrafPtr inPort) {::GetPort (&mSave); ::SetPort (inPort);};
- ~StPortState (void) {::SetPort (mSave);};
- };
-
- and say
-
- StPortState savePort (myPort);
-
- at the top of your routine. No muss no fuss.
-
- - rmgw
-
- http://www.punchdeck.com/hawkfish/PunchDeck.html
-
- - --------------------------------------------------------------------------
- Richard Wesley hawkfish@punchdeck.com | "'Hand it round first, and cut it
- Punch Deck Consulting pnchdeck@aol.com | afterwards.'" - Lewis Carroll,
- Macintosh Software Development | "Through the Looking Glass"
- - --------------------------------------------------------------------------
-
-
-
- +++++++++++++++++++++++++++
-
- >From thor@telerama.lm.com (Tom Moertel)
- Date: Mon, 24 Jul 1995 22:50:05 -0500
- Organization: Management Science Associates, Commercial Software Group
-
- Regarding the age-old controversy of whether or not to save and restore
- the drawing environment, I look to a higher question: Sould we know where
- we are drawing?
-
- The obvious answer is yes. We ought to know where we are drawing. To
- draw haphazardly is to discard order and consistency, to cast away the
- foundation of the Macintosh environment. Thus we create The Fundamental
- Axiom of Drawing: We should always know where we are drawing.
-
- Now, can we derive from the Axiom simple rules ensuring that our code will
- always do the right thing? You betcha.
-
- *** Rule 1 *** Before drawing in an independent routine, explicitly set
- the drawing environment.
-
- Rule 1 ensures that when your routine draws, it knows where it is drawing.
-
- But we still have a problem. What about the routine that called your
- drawing routine? When your routine returns, how can we ensure that the
- caller will still be drawing where it thinks it is? Rule 2 gives the
- answer:
-
- *** Rule 2 *** If your routine changes the drawing environment, make sure
- it restores the environment before returning to the caller.
-
- Rule 2 ensures that if the caller knew where it was drawing when it called
- your routine, it will still know where it is drawing when it regains
- control (because it is drawing in the same place).
-
- These two rules are sufficient to ensure consistency with the Fundamental
- Axiom. If you follow them, your code will always draw in the right place,
- and the world will be more enjoyable for all.
-
- --
- Tom Moertel
- thor@telerama.lm.com
-
- +++++++++++++++++++++++++++
-
- >From carl.gustafson@ece.drexel.edu (Carl Gustafson)
- Date: 24 Jul 1995 13:21:42 GMT
- Organization: Imaging and Computer Vision Center, Drexel University
-
- In article <peter-2307951540530001@adi008.adi.co.nz>, peter@adi.co.nz
- (Peter Bromley) wrote:
-
-
- > Hmmmm, I guess I didnt express myself very clearly. And perhaps you are
- > right - the NIM snippets dont seem to advocate protecting the current port
- > at all. I guess my approach has arisin from discovering that whenever I
- > found a current port related bug (like system font getting trashed, or
- > LocalToGlobal doing weird things) I found that the port was not what I
- > expected. My code policy evolved out from that to the (I guess) paranoid,
- > but safe approach of making sure the port is what I want it to be but -
- > just in case - always restoring the current port as well. I found it was
- > easier to do this as close to my main event loop as possible and got the
- > added bonus that lower level routines could assume the port was always
- > correct.
- >
- > BTW: these problems dont just come up with regard to the current port. I
- > still find it difficult to setle on _one_ scheme for lots of other things,
- > like pen and text settings within a port, foreground colour, and so on.
- > The situation gets trickier, too, when you're not the only one working on
- > a program. Differing approaches can cause lots of obscure bugs in a
- > multi-person project ;-)
-
- I've always considered preserving and restoring the grafport, pen
- settings, handle lock settings, etc. to be good, defensive programming.
- (Mostly defensive against myself, but that's another matter.) It may be a
- PITA to develop the habit, and take an extra minute to paste in the code,
- but it can save much cleanup time later.
-
- --
- Carl Gustafson
- Imaging and Computer Vision Center
- Drexel University, Philadelphia, Penna
- - ----------------------------------------------------------
- I don't speak for Drexel, and Drexel doesn't listen to me...
-
- +++++++++++++++++++++++++++
-
- >From Jim.Spencer@p510.f61.n282.z1.fidonet.org (Jim Spencer)
- Date: 23 Jul 95 10:58:27
- Organization: Magical Mystery
-
- On 7/21/95, kurisuto@babel.ling.upenn.edu emerged from Plato's cave and
- expounded the following to All
-
- ku> *shrug* I wasn't aware that this was an issue on which there is a
- ku> "right" way to do things. Your way works, but I don't see what's
- ku> wrong with my way, as it works too, and doesn't violate any of Apple's
- ku> rules (I think they included GetPort so that you _can_ preserve the
- ku> port, not because you _have_ to).
-
- No, there is a right way. Your code is not the only one using QuickDraw, the
- toolbox itself is if no one else.
-
- ku> Really, I think it's personal preference, and the important thing is
- ku> that you pick a scheme and then _be consistant_ with it. Since none
- ku> of my routines make assumptions about what the port should be (with a
- ku> very few exceptions which I always document clearly in my comments),
- ku> none of them need to preserve it either, and I never run into trouble.
-
- Until the toolbox thinks that the port is set to one thing and in fact it's
- set
- to another then CRASH.
-
- > I _might_ make an exception (i.e. and save and restore the port) if I
- > had some routine which did drawing in a certain port and was frequently
- > called from within other routines which needed the port to be something
- > in particular, so that calling this drawing routine would be
- > transparent. But in practice I find that I never need to do this.
- >
- > See, if you did it _right_, you wouldnt ever need to protect individual
- > routines ever.
- >
- > BTW: If IM says do something, you'ld have to be a fool or an expert to
- > do otherwise (IMO of course).
- >
- ku> I agree that IM should be rigorously followed. But I don't agree that
- ku> I'm outside IM's rules here. I'd be quite shocked to learn that IM
- ku> somewhere says "If your routines change the port internally, they must
- ku> always remember and restore the current port, and if you don't do
- ku> this, your application is likely to break under future system
- ku> releases." The important point is that the port be correctly set at
- ku> times when it matters, and there's more than one overall scheme for
- ku> ensuring that this is so.
-
- This issue is the same as checking for errors. It's a question of how bullet
-
- proof you want your code to be. If you restore the port in your drawing
- functions then it doesn't matter what happens elsewhere. You are making
- assumptions which at best can only be called sloppy in particular that you
- won't make a mistake as your code get's more complicated (I'll grant you this
- isn't much of an issue in a "Hello World!" program but how about in something
- exceeding 100,000 lines??) and that no one other than you will ever work with
- your code. IMHO, you can only be sure that both will be true if you are
- doing
- essentially trivial programs.
-
- +++++++++++++++++++++++++++
-
- >From peter@adi.co.nz (Peter Bromley)
- Date: Wed, 26 Jul 1995 18:51:11 +1200
- Organization: ADInstruments
-
- In article <mouser-2407951158400001@204.191.6.123>, mouser@zercom.net
- (Martin-Gilles Lavoie) wrote:
-
- [SNIP]
- >
- > I've had extensions crewing up my view ports now and then....
-
- Ouch!!!
-
- > ... Some still
- > do. I dont take a chance. As to setting the port to every
- > activate/deactivate events. this may be overkill (although, it doesn't
- > take much CPU time..). To be safe, I always set my port before drawing.
- > On activate, it'd be only usefull if I wanted to track the cursor position
- > relative to the window position.
- >
-
- One of the most common reactions to (de)activate is to add or remove a
- selection (esp calling TEActivate). The current port needs to be set
- correctly for these things to draw right (although TEActivate might be
- paranoid)
-
- Just another $0.02,
-
- --
- Peter Bromley (peter@adi.co.nz)
- ADInstruments, Dunedin, New Zealand
-
- +++++++++++++++++++++++++++
-
- >From peter@stairways.com.au (Peter N Lewis)
- Date: Thu, 27 Jul 1995 20:07:41 +0800
- Organization: Stairways Software
-
- In article <thor-2407952250050001@thor.slip.lm.com>, thor@telerama.lm.com
- (Tom Moertel) wrote:
-
- >The obvious answer is yes. We ought to know where we are drawing. To
- >draw haphazardly is to discard order and consistency, to cast away the
- >foundation of the Macintosh environment. Thus we create The Fundamental
- >Axiom of Drawing: We should always know where we are drawing.
-
- >*** Rule 1 *** Before drawing in an independent routine, explicitly set
- >the drawing environment.
-
- >*** Rule 2 *** If your routine changes the drawing environment, make sure
- >it restores the environment before returning to the caller.
-
- Rule 2 is redundant and not necessary (and ignoring it leads to Sean
- Crist's way of doing it (which is the same as mine, and contrary to
- popular wisdom).
-
- If you draw something, ensure the port is set correctly (Rule 1). If you
- call another routine which may change the port, then re-apply Rule 1.
-
- Obviously, if you are messing around with trap patching and the like, then
- you want to preserve *everything*. Also, if you are in a library routine
- that shouldn't be messing with the port, but does in strange cases, or a
- callback from the OS or something like that where the caller is out of
- your control, then it is defnsive to restore the port.
-
- However, it is not necessarily safe to do so. For example, consider this code:
-
- wp := NewWindow
- SetPort(wp)
- CloseWindow(wp)
- CallYourRoutine
-
- If CallYourRoutine does as suggested by popular wisdom, then it will save
- and restore the port - but the port is currently invalid, so the trailing
- SetPort(savedport) call will be invalid and potentially dangerous! More
- important than Rule 2 is that you should never call SetPort (or any other
- OS routine) with invalid parameters.
- Enjoy,
- Peter.
- --
- It's still easy in Unix:
- ls *.lisp | sed -e 's/\(.*\).lisp$/mv "\1.lisp" "\1.lst"/' | sh
- --Tim Smith <tzs@u.washington.edu>
-
- +++++++++++++++++++++++++++
-
- >From thor@telerama.lm.com (Tom Moertel)
- Date: Fri, 28 Jul 1995 00:49:15 -0500
- Organization: Management Science Associates, Commercial Software Group
-
- In article <peter-2707952007420001@zany.peter.com.au>,
- peter@stairways.com.au (Peter N Lewis) wrote:
-
- > In article <thor-2407952250050001@thor.slip.lm.com>, thor@telerama.lm.com
- > (Tom Moertel) wrote:
- >
- > > [SNIP] Thus we create The Fundamental
- > > Axiom of Drawing: We should always know where we are drawing.
- >
- > >*** Rule 1 *** Before drawing in an independent routine, explicitly set
- > >the drawing environment.
- >
- > >*** Rule 2 *** If your routine changes the drawing environment, make sure
- > >it restores the environment before returning to the caller.
- >
- > Rule 2 is redundant and not necessary (and ignoring it leads to Sean
- > Crist's way of doing it (which is the same as mine, and contrary to
- > popular wisdom).
- >
- > If you draw something, ensure the port is set correctly (Rule 1). If you
- > call another routine which may change the port, then re-apply Rule 1.
-
- If I call a routine that I suspect will muck up the drawing environment, I
- do as you suggest and re-apply rule 1. That's defensive programming.
- However, I draw the line at repeatedly applying rule 1 as my primary
- method of esuring that my code is drawing in the right place with the
- right settings. There are three reasons for my preference:
-
- (1) Applying Rule 1 can be costly. If a routine has special requirements
- for the pen, text face, text size, and so on, repeatedly enforcing
- those requirements can be excessive.
-
- (2) Because of (1), we might be tempted to examine a subroutine before
- calling it just to see what parts of the graphics environment it
- changes, in hopes of have to restore only those parts. Our calling
- routine would thus become dependent on the implementation details
- of the subroutine. I try to reduce dependancy when possible.
-
- (3) Alternatively, we could try to reduce the costs mentioned in (1)
- by having overly graphic subroutines clean up after themselves (in
- essence, applying Rule 2). In that way, callers would need to re-apply
- Rule 1 only to the more commonly changed graphics variables. I
- don't like this arrangement because it's inconsistent. Sometimes
- we use a re-application of Rule 1 and sometimes we use Rule 1 in
- conjunction with Rule 2. That's too confusing for my meager
- brain to handle in the midnight hours, when otherwise good hackin'
- might be disrupted by too much thinkin' ;-)
-
- > Obviously, if you are messing around with trap patching and the like, then
- > you want to preserve *everything*. Also, if you are in a library routine
- > that shouldn't be messing with the port, but does in strange cases, or a
- > callback from the OS or something like that where the caller is out of
- > your control, then it is defnsive to restore the port.
- >
- > However, it is not necessarily safe to do so. For example, consider
- this code:
- >
- > wp := NewWindow
- > SetPort(wp)
- > CloseWindow(wp)
- > CallYourRoutine
- >
- > If CallYourRoutine does as suggested by popular wisdom, then it will save
- > and restore the port - but the port is currently invalid, so the trailing
- > SetPort(savedport) call will be invalid and potentially dangerous!
-
- Hey, that's not fair! ;-) The way I see it, you could remove
- CallYourRoutine altogether and the port will still be hosed. That is,
- unless you think it's a good idea to have CallYourRoutine, a subroutine,
- set up its caller's port as a side effect of its normal operation.
-
- In this case it's clear that if the program wants to draw after it called
- CloseWindow, it had better set up the drawing environment -- regardless of
- what CallYourRoutine does. What's interesting is that even in this
- example, where the port is hosed, CallYourRoutine would have drawn
- properly if it been written with both Rule 1 and Rule 2 in mind.
-
- > More
- > important than Rule 2 is that you should never call SetPort (or any other
- > OS routine) with invalid parameters.
-
- Agreed. But it's hard to ensure that your parameters will always be good
- without the help of a couple rules....
-
- Cheers and fine homebrew,
- Tom
-
- --
- Tom Moertel
- thor@telerama.lm.com
-
- +++++++++++++++++++++++++++
-
- >From Mark Williams <Mark@streetly.demon.co.uk>
- Date: Thu, 27 Jul 95 09:37:56 GMT
- Organization: Streetly Software
-
-
- In article <c1b_9507250800@mmbbs.com>, Jim Spencer writes:
-
- >
- > On 7/21/95, kurisuto@babel.ling.upenn.edu emerged from Plato's cave and
- > expounded the following to All
- >
- > ku> *shrug* I wasn't aware that this was an issue on which there is a
- > ku> "right" way to do things. Your way works, but I don't see what's
- > ku> wrong with my way, as it works too, and doesn't violate any of Apple's
- > ku> rules (I think they included GetPort so that you _can_ preserve the
- > ku> port, not because you _have_ to).
- >
- > No, there is a right way. Your code is not the only one using QuickDraw, the
- > toolbox itself is if no one else.
- >
- > ku> Really, I think it's personal preference, and the important thing is
- > ku> that you pick a scheme and then _be consistant_ with it. Since none
- > ku> of my routines make assumptions about what the port should be (with a
- > ku> very few exceptions which I always document clearly in my comments),
- > ku> none of them need to preserve it either, and I never run into trouble.
- >
- > Until the toolbox thinks that the port is set to one thing and in fact it's
- > set
- > to another then CRASH.
-
- Well, the only toolbox call I can think of which requires a particular port to be set (other than
- the obvious quickdraw calls) is ModalDialog, and thats always struck me as a mistake in the
- documentation - last time I checked it operates on the FrontWindow() not the current port, BWTFDIK.
-
- I suppose the exceptions are callback routines and DefProcs - but here the documentation is
- (usually) very specific about what you need to save and restore.
-
- That objection aside (please dont bother sending me lists of toolbox calls which require a
- particular port to be set), I still dont follow the logic here. There _are_ times when a certain
- port needs to be set - so you just set it. What has that got to do with saving and restoring the
- port?
-
- Look at the way PowerPlant and TCL (and possibly MacApp - I wouldnt know) handle setting the port.
- There is a routine (Prepare, or FocusView - whatever) which sets up the port and coordinate system.
- It gets called whenever a particular view needs to be setup - the frameworks make no attempt to save
- the current port. More significantly, since all the views in a window share a single port, _just_
- saving and restoring the port will do you no good at all - you lose the origin, clipping region and
- any other view-specific environment info (font, pen size, colours etc).
-
- >
- > [snip]
- > This issue is the same as checking for errors. It's a question of how bullet
- >
- > proof you want your code to be. If you restore the port in your drawing
- > functions then it doesn't matter what happens elsewhere. You are making
- > assumptions which at best can only be called sloppy in particular that you
- > won't make a mistake as your code get's more complicated (I'll grant you this
- > isn't much of an issue in a "Hello World!" program but how about in something
- > exceeding 100,000 lines??) and that no one other than you will ever work with
- > your code. IMHO, you can only be sure that both will be true if you are
- > doing
- > essentially trivial programs.
-
- Wow.
-
- All TCL and PowerPlant apps are trivial.
-
- - --------------------------------------
- Mark Williams<Mark@streetly.demon.co.uk>
-
- +++++++++++++++++++++++++++
-
- >From ldo@waikato.ac.nz (Lawrence D’Oliveiro)
- Date: Fri, 28 Jul 1995 19:53:13 +1200
- Organization: University of Waikato
-
- In article <peter-2707952007420001@zany.peter.com.au>,
- peter@stairways.com.au (Peter N Lewis) wrote:
-
- >However, it is not necessarily safe to do so. For example, consider this code:
- >
- >wp := NewWindow
- >SetPort(wp)
- >CloseWindow(wp)
- >CallYourRoutine
- >
- >If CallYourRoutine does as suggested by popular wisdom, then it will save
- >and restore the port - but the port is currently invalid, so the trailing
- >SetPort(savedport) call will be invalid and potentially dangerous!
-
- I disagree. I don't think there is anything wrong with doing a SetPort to
- an invalid port, just so long as you don't try to draw to it. And if every
- piece of code is explicitly doing a SetPort before doing their drawing,
- you'll never hit the problem!
-
- Consider also what happens after the initial InitGraf call: the current
- port is undefined then, too.
-
- In short, it seems to me the current semantics of SetPort is: it's OK to
- use it to restore whatever value you previously got from GetPort, even if
- that value is not a valid port. Somehow I don't think that aspect of the
- semantics will ever change, since it just makes things too complicated
- otherwise.
-
- Lawrence "QuickDraw GX doesn't have this problem" D'Oliveiro
-
- +++++++++++++++++++++++++++
-
- >From stk@berlin.snafu.de (Stefan Kurth)
- Date: Fri, 28 Jul 1995 13:22:43 +0200
- Organization: none
-
- Peter N Lewis <peter@stairways.com.au> wrote:
-
- > In article <thor-2407952250050001@thor.slip.lm.com>, thor@telerama.lm.com
- > (Tom Moertel) wrote:
- >
- > >*** Rule 1 *** Before drawing in an independent routine, explicitly set
- > >the drawing environment.
- >
- > >*** Rule 2 *** If your routine changes the drawing environment, make sure
- > >it restores the environment before returning to the caller.
- >
- > Rule 2 is redundant and not necessary (and ignoring it leads to Sean
- > Crist's way of doing it (which is the same as mine, and contrary to
- > popular wisdom).
- >
- > If you draw something, ensure the port is set correctly (Rule 1). If you
- > call another routine which may change the port, then re-apply Rule 1.
-
- Peter, I can't believe that you wrote this. No offence, but this has
- very little to do with modern programming techniques. It requires that
- for every routine that you call you have to know whether it can possibly
- change the current port. This is not desirable, especially in multi-
- person projects.
-
- A much better design is to make sure that none of your routines have any
- side effects whatsoever, like changing global variables, or changing the
- drawing environment or the current port (which is just a global variable
- after all).
-
- Suppose you have something like this:
-
- SetPort(myWindow);
- /* draw something here */
- SomeRoutine();
- /* draw something else here */
-
- You don't set the port again after SomeRoutine(), because you know that
- this routine doesn't change the port. Now, 1/2 year later you make
- modifications to SomeRoutine so that it now does change the current port
- for some reason (or calls another routine that does). So you now have
- to go through your entire program, find all calls to SomeRoutine, and
- insert SetPort's all over the place. Frankly, I wouldn't want to have
- to maintain your program.
-
- > wp := NewWindow
- > SetPort(wp)
- > CloseWindow(wp)
- > CallYourRoutine
- >
- > If CallYourRoutine does as suggested by popular wisdom, then it will save
- > and restore the port - but the port is currently invalid, so the trailing
- > SetPort(savedport) call will be invalid and potentially dangerous! More
- > important than Rule 2 is that you should never call SetPort (or any other
- > OS routine) with invalid parameters.
-
- There is nothing to worry about here. Invalid parameter? Maybe, but we
- got that parameter from GetPort earlier, so it must be valid enough for
- the OS. And whether the port was valid before we were called, or will
- be valid after we return, is not something we should care about. We
- just set everything back to what it was, and this is no more dangerous
- than if we hadn't been called at all.
-
- The only place where you would have to worry about the port being
- invalid is in the routine that calls CloseWindow, but nowhere else.
-
- ________________________________________________________________________
- Stefan Kurth Berlin, Germany stk@berlin.snafu.de
-
- +++++++++++++++++++++++++++
-
- >From mhl@icf.hrb.com (Mark H. Linton)
- Date: 27 Jul 95 18:00:55 EST
- Organization: HRB Systems, Inc.
-
- In article <thor-2407952250050001@thor.slip.lm.com>,
- thor@telerama.lm.com (Tom Moertel) wrote:
-
- >Thus we create The Fundamental Axiom of Drawing:
- > We should always know where we are drawing.
- >
- >*** Rule 1 *** Before drawing in an independent routine, explicitly set
- >the drawing environment.
- >
- >*** Rule 2 *** If your routine changes the drawing environment, make sure
- >it restores the environment before returning to the caller.
- >
-
- I am afraid I agree with Tom on this.
-
- Just to get all of you who are less than defensive, I am going to
- write an extension which installs a global jGNE filter -- whose
- only purpose in life is to:
-
- a) screw up the current graphics port (i.e. set it to something
- other than it was before)
-
- b) screw up the graphics pen (e.g., set its width to 32768 x
- 32768, etc.)
-
- If your screen doesn't get wacky, then your coding technique
- obviously works. Otherwise not...
-
- BTW, the suggested Get, Set, Draw, Set sequence will always work
- in a cooperative multitasking environment in the presence of such
- a filter.
-
- --
- Hope this helps.
-
- Mark H. Linton
- ____________________________________________________________________
- mark \'märk\ n [ME, fr. OE mearc boundary, march, sign; akin to OHG
- marha boundary, L margo] 1 a : a conspicuous object serving as a guide
- for travelers 2 : A standard or criterion of quality 3 : An object or
- point that serves as a guide --idiom. mark time. 1 : To make little or
- no progress
-
- +++++++++++++++++++++++++++
-
- >From pottier@jonque.ens.fr (Francois Pottier)
- Date: 28 Jul 1995 15:10:19 GMT
- Organization: Ecole Normale Superieure, Paris
-
- In article <thor-2807950049150001@thor.slip.lm.com>,
- Tom Moertel <thor@telerama.lm.com> wrote:
-
- >(1) Applying Rule 1 can be costly. If a routine has special requirements
- > for the pen, text face, text size, and so on, repeatedly enforcing
- > those requirements can be excessive.
- >
- >(2) Because of (1), we might be tempted to examine a subroutine before
- > calling it just to see what parts of the graphics environment it
- > changes, in hopes of have to restore only those parts.
-
- I understand these problems. I suggest you have a look at the way they
- are handled in PowerPlant. PowerPlant only uses Rule 1. This means that
- no assumptions are made about the current port, and a routine has to
- set the graphic environment by calling FocusDraw() before drawing.
- So a PowerPlant program ends up calling FocusDraw() many times. But
- the implementation of FocusDraw() remembers if it has already been
- called, so it costs almost nothing to call it too often. I think it's
- a good solution.
-
- --
- Francois Pottier pottier@dmi.ens.fr
- - ----------------------------------------------------------------------------
- Check my WWW page at http://acacia.ens.fr:8080/home/pottier/ ...
-
- +++++++++++++++++++++++++++
-
- >From pottier@jonque.ens.fr (Francois Pottier)
- Date: 28 Jul 1995 15:15:55 GMT
- Organization: Ecole Normale Superieure, Paris
-
- In article <1995072813224396868@stk.berlin.snafu.de>,
- Stefan Kurth <stk@berlin.snafu.de> wrote:
-
- >> If you draw something, ensure the port is set correctly (Rule 1). If you
- >> call another routine which may change the port, then re-apply Rule 1.
- >
- >Peter, I can't believe that you wrote this. No offence, but this has
- >very little to do with modern programming techniques. It requires that
- >for every routine that you call you have to know whether it can possibly
- >change the current port. This is not desirable, especially in multi-
- >person projects.
-
- I agree that it is not desirable - but it is *not* necessary. Just
- assume that *every* subroutine changes the port. Always set it before
- drawing.
-
- As I pointed out in another message, setting the graphics environment
- every time you think it might have changed is not costly if you have
- a smart implementation. Look at PowerPlant - it remembers which pane
- is currently in focus.
-
- About the port being invalid, it's nothing to worry about, as long as
- you apply rule 1 and set it before drawing.
-
- Cheers,
-
-
-
- --
- Francois Pottier pottier@dmi.ens.fr
- - ----------------------------------------------------------------------------
- Check my WWW page at http://acacia.ens.fr:8080/home/pottier/ ...
-
- +++++++++++++++++++++++++++
-
- >From ingemar@lysator.liu.se (Ingemar Ragnemalm)
- Date: 29 Jul 1995 19:22:39 GMT
- Organization: (none)
-
- >>> Duncan Thomson <duncant@sushi.mitre.or.jp> wrote:
- >>> >Hi, Mac programming novice here with a question...
- >>> >
- >>> >The "Inside Mac" books say that, before setting the current port (when you
- >>> >want to draw in it), you should save the previous port, then, after you
- >>> >are done drawing, set it back to what it was. (Written in a confusing
- >>> >manner, I admit, but I think you know what I'm talking about.)
- >>> >
- >>> >My question: Is this really necessary? If all code sets the port as
- >>> >necessary before drawing in it, why bother to restore it? Is there some
- >>> >problem with asynchronous processing going on here?
-
- No, you don't HAVE to restore the port, but it is a very good habit. If all
- utility functions, routines that fire up dialogs etc, restore the port, you
- can call them any time. If you are careless, you will have to put SetPort's
- all over the place.
-
- --
- - -
- Ingemar Ragnemalm, PhD
- Image processing, Mac shareware games
- E-mail address: ingemar@isy.liu.se or ingemar@lysator.liu.se
-
- +++++++++++++++++++++++++++
-
- >From kenp@nmrfam.wisc.edu (Ken Prehoda)
- Date: Tue, 01 Aug 1995 10:00:42 -0500
- Organization: Univ of Wisc-Madison, Dept of Biochemistry
-
- In article <ldo-2807951953130001@130.217.96.144>, ldo@waikato.ac.nz wrote:
-
- : In article <peter-2707952007420001@zany.peter.com.au>,
- : peter@stairways.com.au (Peter N Lewis) wrote:
- :
- : >However, it is not necessarily safe to do so. For example, consider
- this code:
- : >
- : >wp := NewWindow
- : >SetPort(wp)
- : >CloseWindow(wp)
- : >CallYourRoutine
- : >
- : >If CallYourRoutine does as suggested by popular wisdom, then it will save
- : >and restore the port - but the port is currently invalid, so the trailing
- : >SetPort(savedport) call will be invalid and potentially dangerous!
- :
- : I disagree. I don't think there is anything wrong with doing a SetPort to
- : an invalid port, just so long as you don't try to draw to it. And if every
- : piece of code is explicitly doing a SetPort before doing their drawing,
- : you'll never hit the problem!
- :
- : Consider also what happens after the initial InitGraf call: the current
- : port is undefined then, too.
- :
- : In short, it seems to me the current semantics of SetPort is: it's OK to
- : use it to restore whatever value you previously got from GetPort, even if
- : that value is not a valid port. Somehow I don't think that aspect of the
- : semantics will ever change, since it just makes things too complicated
- : otherwise.
- :
- : Lawrence "QuickDraw GX doesn't have this problem" D'Oliveiro
-
- It all depends on how you use Quickdraw GX. If you use the:
-
- gxRectangle rectGeom = {...};
- gxShape rect = GXNewRectangle(&rectGeom);
- GXSetShapeViewPorts(rect,...);
-
- method, then sure you don't have to worry about the "current port". But
- there is the disadvantage of creating an object in the GX heap that you
- could potentially leave around for awhile.
-
- GX also has these types of calls though:
-
- gxRectangle rectGeom = {...};
-
- GXDrawRectangle(&rectGeom,...);
-
- and if you use these types, then you certainly do have to worry about the
- "current port" (or default shapes as they are called in GX). It is also
- interesting to note that these calls are quite a bit faster than the ones
- given in the above example.
-
- --
- Ken Prehoda, kenp@nmrfam.wisc.edu
-
- +++++++++++++++++++++++++++
-
- >From kenp@nmrfam.wisc.edu (Ken Prehoda)
- Date: Tue, 01 Aug 1995 10:00:42 -0500
- Organization: Univ of Wisc-Madison, Dept of Biochemistry
-
- In article <ldo-2807951953130001@130.217.96.144>, ldo@waikato.ac.nz wrote:
-
- : In article <peter-2707952007420001@zany.peter.com.au>,
- : peter@stairways.com.au (Peter N Lewis) wrote:
- :
- : >However, it is not necessarily safe to do so. For example, consider
- this code:
- : >
- : >wp := NewWindow
- : >SetPort(wp)
- : >CloseWindow(wp)
- : >CallYourRoutine
- : >
- : >If CallYourRoutine does as suggested by popular wisdom, then it will save
- : >and restore the port - but the port is currently invalid, so the trailing
- : >SetPort(savedport) call will be invalid and potentially dangerous!
- :
- : I disagree. I don't think there is anything wrong with doing a SetPort to
- : an invalid port, just so long as you don't try to draw to it. And if every
- : piece of code is explicitly doing a SetPort before doing their drawing,
- : you'll never hit the problem!
- :
- : Consider also what happens after the initial InitGraf call: the current
- : port is undefined then, too.
- :
- : In short, it seems to me the current semantics of SetPort is: it's OK to
- : use it to restore whatever value you previously got from GetPort, even if
- : that value is not a valid port. Somehow I don't think that aspect of the
- : semantics will ever change, since it just makes things too complicated
- : otherwise.
- :
- : Lawrence "QuickDraw GX doesn't have this problem" D'Oliveiro
-
- It all depends on how you use Quickdraw GX. If you use the:
-
- gxRectangle rectGeom = {...};
- gxShape rect = GXNewRectangle(&rectGeom);
- GXSetShapeViewPorts(rect,...);
-
- method, then sure you don't have to worry about the "current port". But
- there is the disadvantage of creating an object in the GX heap that you
- could potentially leave around for awhile.
-
- GX also has these types of calls though:
-
- gxRectangle rectGeom = {...};
-
- GXDrawRectangle(&rectGeom,...);
-
- and if you use these types, then you certainly do have to worry about the
- "current port" (or default shapes as they are called in GX). It is also
- interesting to note that these calls are quite a bit faster than the ones
- given in the above example.
-
- --
- Ken Prehoda, kenp@nmrfam.wisc.edu
-
- ---------------------------
-
- >From tmorrow@us.oracle.com (tmorrow)
- Subject: Where are my command line arguments?
- Date: 29 Jul 1995 00:19:26 GMT
- Organization: Oracle Corporation. Redwood Shores, CA
-
-
- We are in the process of porting some batch programs over to the
- Macintosh from UNIX, and realizing that the Mac has no command line
- argument interface for invoking executables.
-
- This is a major bummer, and are curious about what other people have
- done in this type of situation.
-
- We basically have one program which sequentially spawns processes to do
- various batch type tasks, communicating important paramters to the
- child processes through the command line. We have thought of using
- files to communicate the same information that we communicated on the
- command line in UNIX. The files would be the documents in Mac's
- document-centric interface; invoking (opening) a file of command line
- arguments would be equivalent to invoking an application with those
- command line arguments on UNIX. Another idea would be apple events,
- but that would probably require even more "nativising" which we don't
- want to do if we don't have to.
-
- Is there some kind of library or some other simple solution that won't
- require as much native coding as using files of arguments or passing
- the arguments through apple events? Ideally there would be a way to
- keep the argc, argv processing code just the way it is on UNIX.
-
- It seems like a glaring deficiency that the Mac has no way of passing
- paramters to an application upon startup, but I guess that is due to
- its document-centric design, eh?
-
- Please copy me via email if you respond.
-
- Thanks!
-
- -Tom Morrow
- tmorrow@us.oracle.com
-
-
-
-
-
-
- +++++++++++++++++++++++++++
-
- >From fesh@applelink.apple.com (TheBug)
- Date: 29 Jul 1995 13:30:30 GMT
- Organization: privat
-
- In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com>,
- tmorrow@us.oracle.com (tmorrow) wrote:
-
- > We are in the process of porting some batch programs over to the
- > Macintosh from UNIX, and realizing that the Mac has no command line
- > argument interface for invoking executables.
- >
- > This is a major bummer, and are curious about what other people have
- > done in this type of situation.
- >
- > We basically have one program which sequentially spawns processes to do
- > various batch type tasks, communicating important paramters to the
- > child processes through the command line. We have thought of using
- > files to communicate the same information that we communicated on the
- > command line in UNIX. The files would be the documents in Mac's
- > document-centric interface; invoking (opening) a file of command line
- > arguments would be equivalent to invoking an application with those
- > command line arguments on UNIX. Another idea would be apple events,
- > but that would probably require even more "nativising" which we don't
- > want to do if we don't have to.
- >
- > Is there some kind of library or some other simple solution that won't
- > require as much native coding as using files of arguments or passing
- > the arguments through apple events? Ideally there would be a way to
- > keep the argc, argv processing code just the way it is on UNIX.
- >
- > It seems like a glaring deficiency that the Mac has no way of passing
- > paramters to an application upon startup, but I guess that is due to
- > its document-centric design, eh?
-
- Hope you intend to use this only in-house and have no intention to sell
- it. If you try to sell such a solution to the Mac community I would rather
- suggest to stop right now and not waste your energy. Any magazine review
- of such a program would be a bad bashing up.
-
- If this program is for end user sales you will have to go the full way and
- make it a real Mac application, otherwise you will get buried in the
- market. Mac users are kind of allergic to "cheap ports".
-
- If this is just for in-house use you should get yourself MPW from Apple.
- This is basically a development environment but it offers you standard
- command line interfacing with argc, argv, output redirection and all the
- stuff.
-
- +++++++++++++++++++++++++++
-
- >From Richard Wesley <hawkfish@punchdeck.com>
- Date: 29 Jul 1995 16:02:37 GMT
- Organization: Punch Deck Consulting
-
- tmorrow@us.oracle.com (tmorrow) wrote:
- >
- >We are in the process of porting some batch programs over to the
- >Macintosh from UNIX, and realizing that the Mac has no command line
- >argument interface for invoking executables.
- >
- >This is a major bummer, and are curious about what other people have
- >done in this type of situation.
- >
- >We basically have one program which sequentially spawns processes to do
- >various batch type tasks, communicating important paramters to the
- >child processes through the command line. We have thought of using
- >files to communicate the same information that we communicated on the
- >command line in UNIX. The files would be the documents in Mac's
- >document-centric interface; invoking (opening) a file of command line
- >arguments would be equivalent to invoking an application with those
- >command line arguments on UNIX. Another idea would be apple events,
- >but that would probably require even more "nativising" which we don't
- >want to do if we don't have to.
- >
- >Is there some kind of library or some other simple solution that won't
- >require as much native coding as using files of arguments or passing
- >the arguments through apple events? Ideally there would be a way to
- >keep the argc, argv processing code just the way it is on UNIX.
- >
- >It seems like a glaring deficiency that the Mac has no way of passing
- >paramters to an application upon startup, but I guess that is due to
- >its document-centric design, eh?
-
- There _is_ a way to do this - AppleEvents. All you have to do
- is define your own AE that passes a command line. Then you can write one
- bottleneck routine that takes a process name and a command line and
- launches the process with the given AE. Each process then just needs a
- shell that recieves the AE and breaks it up for your "main".
-
- - rmgw
-
- http://www.punchdeck.com/hawkfish/PunchDeck.html
-
- - --------------------------------------------------------------------------
- Richard Wesley hawkfish@punchdeck.com | "'Hand it round first, and cut it
- Punch Deck Consulting pnchdeck@aol.com | afterwards.'" - Lewis Carroll,
- Macintosh Software Development | "Through the Looking Glass"
- - --------------------------------------------------------------------------
-
-
-
- +++++++++++++++++++++++++++
-
- >From 3gl21@qlink.queensu.ca (Gregory Lo)
- Date: Sat, 29 Jul 1995 22:13:25 -0400
- Organization: Queen's University
-
- In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com>,
- tmorrow@us.oracle.com (tmorrow) wrote:
-
- > We are in the process of porting some batch programs over to the
- > Macintosh from UNIX, and realizing that the Mac has no command line
- > argument interface for invoking executables.
-
- > We basically have one program which sequentially spawns processes to do
- > various batch type tasks, communicating important paramters to the
- > child processes through the command line. We have thought of using
- > files to communicate the same information that we communicated on the
- > command line in UNIX. The files would be the documents in Mac's
- > document-centric interface; invoking (opening) a file of command line
- > arguments would be equivalent to invoking an application with those
- > command line arguments on UNIX.
-
- Don't do this. No Mac end-user would ever want to bother with this hassle.
-
- > Another idea would be apple events,
- > but that would probably require even more "nativising" which we don't
- > want to do if we don't have to.
-
- This is the way to go. (You would recieve Apple Events, anyway)
- Apple Events are _the_ medium of interapplication communication in MacOS.
- Their use is standard and necessary for later versions of MacOS.
-
- > Is there some kind of library or some other simple solution that won't
- > require as much native coding as using files of arguments or passing
- > the arguments through apple events? Ideally there would be a way to
- > keep the argc, argv processing code just the way it is on UNIX.
-
- Most commercial compilers will include console interfaces and libraries to
- ease porting of programs from other platforms. Or, you could use MPW, but
- then your program could only be used from within the MPW environment.
-
- > It seems like a glaring deficiency that the Mac has no way of passing
- > paramters to an application upon startup, but I guess that is due to
- > its document-centric design, eh?
-
- Actually, you _do_ get information passed to your application upon startup
- anyway via one of three of the four _required_ Apple Events: "Open
- Application", "Open Document(s)", "Print Document(s)".
- Creating files and then opening them as a means of passing parameters ends
- up creating and sending "Open Document" Apple Events, anyway. If your
- application were properly written for MacOS, it should be no trouble to
- extend to the use of other Apple Events. I'm sure there are libraries and
- frameworks to make this incredibly easy for you.
-
- A third alternative is to make use of threads. Threads operate similiarly
- on almost all platforms and OS' that support them. Your UN*X probably
- supports the use of threads. Beware, though, that pre-emptive threads in
- MacOS are now only supported on 68K machines, using System 7.5 or later,
- or using System 7.1 with the Thread Manager extension.
-
- GLo
-
- ps. I've never really considered the Mac as a document-centric interface.
- I just don't see how it would differ from other OS' (like UN*X) in that
- respect. OLE and OpenDoc, I would consider document-centric interfaces.
-
- - ---------------------------------------------------------
- Gregory Lo GLo ?:^(> <mailto:3gl21@qlink.queensu.ca>
-
- +++++++++++++++++++++++++++
-
- >From ckt@best.com (Chris Thomas)
- Date: Sat, 29 Jul 1995 20:36:29 -0800
- Organization: Echo Software
-
- In article <fesh-2907951530280001@async107.zrz.tu-berlin.de>,
- fesh@applelink.apple.com (TheBug) wrote:
-
- > In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com>,
- > tmorrow@us.oracle.com (tmorrow) wrote:
- >
- > > We are in the process of porting some batch programs over to the
- > > Macintosh from UNIX, and realizing that the Mac has no command line
- > > argument interface for invoking executables.
- > >
- > > This is a major bummer, and are curious about what other people have
- > > done in this type of situation.
- > >
- > > We basically have one program which sequentially spawns processes to do
- > > various batch type tasks, communicating important paramters to the
- > > child processes through the command line. We have thought of using
- > > files to communicate the same information that we communicated on the
- > > command line in UNIX. The files would be the documents in Mac's
- > > document-centric interface; invoking (opening) a file of command line
- > > arguments would be equivalent to invoking an application with those
- > > command line arguments on UNIX. Another idea would be apple events,
- > > but that would probably require even more "nativising" which we don't
- > > want to do if we don't have to.
- > >
- > > Is there some kind of library or some other simple solution that won't
- > > require as much native coding as using files of arguments or passing
- > > the arguments through apple events? Ideally there would be a way to
- > > keep the argc, argv processing code just the way it is on UNIX.
- > >
- > > It seems like a glaring deficiency that the Mac has no way of passing
- > > paramters to an application upon startup, but I guess that is due to
- > > its document-centric design, eh?
- >
- > Hope you intend to use this only in-house and have no intention to sell
- > it. If you try to sell such a solution to the Mac community I would rather
- > suggest to stop right now and not waste your energy. Any magazine review
- > of such a program would be a bad bashing up.
- >
- > If this program is for end user sales you will have to go the full way and
- > make it a real Mac application, otherwise you will get buried in the
- > market. Mac users are kind of allergic to "cheap ports".
- >
- > If this is just for in-house use you should get yourself MPW from Apple.
- > This is basically a development environment but it offers you standard
- > command line interfacing with argc, argv, output redirection and all the
- > stuff.
-
- Also, don't forget that the AppleEvent manager *is* the Mac version
- of command-line arguments- difference being that AppleEvents are
- highly typed. You'll have to nativize if you expect to reap the
- benefits of the Macintosh architecture.
-
- --
- Chris Thomas, ckt@best.com
-
- +++++++++++++++++++++++++++
-
- >From jthill@netcom.com (Jim Hill)
- Date: Sun, 30 Jul 1995 06:39:45 GMT
- Organization: biological <-- hey! a one-word oxymoron!
-
- In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com>,
- tmorrow@us.oracle.com (tmorrow) wrote:
-
- >We are in the process of porting some batch programs over to the
- >Macintosh from UNIX, and realizing that the Mac has no command line
- >argument interface for invoking executables.
-
- I think Greg Lo hit the nail on the head; this is just another take on the
- same idea.
-
- There are lots of ways to do what you want, but as you've noticed they're
- all different from what UNIX does, and (csmp.misc guys, come on, let's
- admit this) it's a pain in the butt when you're porting. But as Greg
- pointed out, if you don't do the work you don't have a Mac program, and if
- Mac users see it they'll leave you on the shelf.
-
- When launching programs, you can specify an apple event to feed them on
- startup. It can be anything you want. You can build it yourself, get it
- from a document, whatever. You wrote the code on both ends, so if you're
- really into not porting you can just make up a command-line apple event;
- it'll be the first thing your code sees and if I recall the Oracle coding
- guidelines correctly you've got an s0-prefix main on every one of them
- anyway.
-
- Given time, I'd go farther and just bypass out the command-line processing
- completely, using appleevents instead: run transactions that have the
- parameters already digested and a list of docs (or whatever) to run them
- on, and have both the unix cmdline parsing and mac appleevent breakout
- drive exactly the same processing code.
-
-
- Just riffing,
- Jim
-
- obStuffIApologizeForNotDeleting:
- At any rate, IM-Processes has lots of good stuff along these lines. Try
- scripting a UNIX process sometime :-) -- "expect" is a gross, limited
- hack. I guess that is due to UNIX's keyboard-centric design, eh? ;-)
- --
- Jim Hill Contents public domain and worth $.02 more than you paid.
- jthill@netcom.com PGPrint: 6B 85 76 D1 EF BA 2C 78 12 25 8A 5A BF F3 37 7E
-
- +++++++++++++++++++++++++++
-
- >From Manuel Veloso <veloso@RT66.com>
- Date: 1 Aug 1995 14:58:07 GMT
- Organization: Ibex Productions
-
- In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com> tmorrow,
- tmorrow@us.oracle.com writes:
- >Is there some kind of library or some other simple solution that won't
- >require as much native coding as using files of arguments or passing
- >the arguments through apple events? Ideally there would be a way to
- >keep the argc, argv processing code just the way it is on UNIX.
- >
-
- Well, if it's not going to be public, how about using MPW?
- You guys probably have a copy in-house somewhere.
-
- The only downsides are that you can't launch a tool from another
- tool, and everything's linear (ie: tool/script/tool/tool).
-
- Another option is to applescript it, with each batch program being
- an OSAXen and an applescript being the makefile/driver equivalent.
- Putting a shell around your programs that extracts params from
- the AppleEvents, transforms them into argv/argc, and returns values
- shouldn't be that hard.
-
- Manuel
-
- +++++++++++++++++++++++++++
-
- >From Manuel Veloso <veloso@RT66.com>
- Date: 1 Aug 1995 14:58:07 GMT
- Organization: Ibex Productions
-
- In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com> tmorrow,
- tmorrow@us.oracle.com writes:
- >Is there some kind of library or some other simple solution that won't
- >require as much native coding as using files of arguments or passing
- >the arguments through apple events? Ideally there would be a way to
- >keep the argc, argv processing code just the way it is on UNIX.
- >
-
- Well, if it's not going to be public, how about using MPW?
- You guys probably have a copy in-house somewhere.
-
- The only downsides are that you can't launch a tool from another
- tool, and everything's linear (ie: tool/script/tool/tool).
-
- Another option is to applescript it, with each batch program being
- an OSAXen and an applescript being the makefile/driver equivalent.
- Putting a shell around your programs that extracts params from
- the AppleEvents, transforms them into argv/argc, and returns values
- shouldn't be that hard.
-
- Manuel
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-